# -*- coding: utf-8 -*-
import sys

sys.path.append('../..')
from common.config import *
from db.mysql import MysqlClient
from itertools import product
import requests, json
from common.helper import Helper
import time
from threading import Thread
import hmac
import execjs
import hashlib
from pprint import pprint


class Spider(object):
    def __init__(self):
        self.mysql = MysqlClient()
        self.name = "百年超倍保重大疾病保险"

    # 生产产品数据
    def genProductInfo(self):
        plan = {
            "planA": {
                # 年龄段
                "year": [str(i) for i in range(0, 11)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": ["Y", "N"],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "20", "30"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["1"]
            },
            "planB": {
                # 年龄段
                "year": [str(i) for i in range(0, 11)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": [""],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "20", "30"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["0"]
            },
            "planC": {
                # 年龄段
                "year": [str(i) for i in range(11, 31)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": ["Y", "N"],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "20", "30"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000", "500000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["1"]
            },
            "planD": {
                # 年龄段
                "year": [str(i) for i in range(11, 31)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": [""],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "20", "30"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000", "500000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["0"]
            },
            "planE": {
                # 年龄段
                "year": [str(i) for i in range(31, 36)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": ["Y", "N"],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "20"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000", "500000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["1"]
            },
            "planF": {
                # 年龄段
                "year": [str(i) for i in range(31, 36)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": [""],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "20"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000", "500000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["0"]
            },
            "planG": {
                # 年龄段
                "year": [str(i) for i in range(36, 41)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": ["Y", "N"],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "15"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000", "500000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["1"]
            },
            "planH": {
                # 年龄段
                "year": [str(i) for i in range(36, 41)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": [""],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "15"],
                # 保障金额
                "money": ["100000", "200000", "300000", "400000", "500000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["0"]
            },
            "planJ": {
                # 年龄段
                "year": [str(i) for i in range(41, 46)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": ["Y", "N"],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10"],
                # 保障金额
                "money": ["100000", "150000", "200000", "300000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["1"]
            },
            "planK": {
                # 年龄段
                "year": [str(i) for i in range(41, 46)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": [""],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5", "10", "15"],
                # 保障金额
                "money": ["100000", "150000", "200000", "300000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["0"]
            },
            "planL": {
                # 年龄段
                "year": [str(i) for i in range(46, 51)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": ["Y", "N"],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5"],
                # 保障金额
                "money": ["100000", "150000", "200000", "300000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["1"]
            },
            "planQ": {
                # 年龄段
                "year": [str(i) for i in range(46, 51)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": [""],
                # 保障期限
                "expire": ["70岁", "终身"],
                # 交费间隔
                "interval": ["5"],
                # 保障金额
                "money": ["100000", "150000", "200000", "300000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["0"]
            },
            "planW": {
                # 年龄段
                "year": [str(i) for i in range(51, 56)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": ["Y", "N"],
                # 保障期限
                "expire": ["终身"],
                # 交费间隔
                "interval": ["5", "10"],
                # 保障金额
                "money": ["100000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["1"]
            },
            "planR": {
                # 年龄段
                "year": [str(i) for i in range(51, 56)],
                # 性别
                "gender": ["M", "F"],
                # 医疗保险
                "socialSec": [""],
                # 保障期限
                "expire": ["终身"],
                # 交费间隔
                "interval": ["5", "10"],
                # 保障金额
                "money": ["100000"],
                # 交费类型
                "payType": ["年交"],
                # 恶性肿瘤
                "seriousCancer": ["0", "1"],
                # 心脑血管疾病
                "heartHeadDisease": ["0", "1"],
                # 医疗责任
                "medicalDuty": ["0"]
            },

        }

        for k in plan:
            for v in product(plan[k]["year"], plan[k]["gender"], plan[k]["socialSec"], plan[k]["expire"],
                             plan[k]["interval"], plan[k]["money"], plan[k]["payType"], plan[k]["seriousCancer"],
                             plan[k]["heartHeadDisease"], plan[k]["medicalDuty"]):
                data = Helper.formatProductInfo(plan[k], v)

                data["seriousCancer"] = data["money"] if data["seriousCancer"] != "0" else "0"
                data["heartHeadDisease"] = data["money"] if data["heartHeadDisease"] != "0" else "0"

                self.mysql.cursor.execute(domain[self.name]["insert_sql"].format(**data))
                self.mysql._conn.commit()
                print(domain[self.name]["insert_sql"].format(**data))

    # 执行爬虫
    def requestJson(self, dt=None, mysql=None):
        # 时间戳
        timestamp = int(time.time() * 1000)
        app_nonce = self.genAppParam()
        app_device = self.genAppParam()
        # 出生年份
        year = str(2020 - int(dt["year"]))
        # 成年code
        appnt = '"CH"' if int(dt["year"]) < 18 else '"SF"'
        # 保障期限
        expire = "106" if dt["expire"] != "70岁" else "70"
        if dt["seriousCancer"] != "0":
            if dt["heartHeadDisease"] == "0":
                dutyCode = "5317D2"
            else:
                dutyCode = "5317D4"
        else:
            if dt["heartHeadDisease"] == "0":
                dutyCode = "5317D1"
            else:
                dutyCode = "5317D3"

        if dt["medicalDuty"] == "1":

            if dt["socialSec"] == "N":
                # post body
                data = '{"appntInfo":{"age":22,"birthday":"1998-05-11","ifSmoke":"N","occupationCode":"3030101","sex":"M","socialSecurityFlag":"N"},"cvalidate":"2020-5-12","insuredInfo":{"age":' + \
                       dt[
                           "year"] + ',"birthday":"' + year + '-01-01","ifSmoke":"N","occupationCode":"3030101","sex":"' + \
                       dt[
                           "gender"] + '","socialSecurityFlag":"N"},"insuredRelationToAppnt":' + appnt + ',"policyInfoList":[{"amnt":"' + \
                       dt[
                           "money"] + '","dutyCode":"' + dutyCode + '","familyType":"","getRate":"","getYear":"","getYearFlag":"","insuredYear":' + expire + ',"insuredYearFlag":"A","mult":1,"payEndYear":' + \
                       dt[
                           "interval"] + ',"payEndYearFlag":"Y","payIntv":"12","prem":"5457","renewalFlag":"NC","riskCode":"5317","getLimit":"","cvalidate":"2020-5-12"},' + '{"amnt":"2000000","dutyCode":"5031D1","familyType":"","getRate":"","getYear":"","getYearFlag":"","insuredYear":1,"insuredYearFlag":"Y","mult":1,"payEndYear":1,"payEndYearFlag":"Y","payIntv":"12","prem":"232","renewalFlag":"NC","riskCode":"5031","getLimit":""}' + '],"saleChnl":"O"}'
            else:
                data = '{"appntInfo":{"age":22,"birthday":"1998-05-11","ifSmoke":"N","occupationCode":"3030101","sex":"M","socialSecurityFlag":"N"},"cvalidate":"2020-5-12","insuredInfo":{"age":' + \
                       dt[
                           "year"] + ',"birthday":"' + year + '-01-01","ifSmoke":"N","occupationCode":"3030101","sex":"' + \
                       dt[
                           "gender"] + '","socialSecurityFlag":"Y"},"insuredRelationToAppnt":' + appnt + ',"policyInfoList":[{"amnt":"' + \
                       dt[
                           "money"] + '","dutyCode":"' + dutyCode + '","familyType":"","getRate":"","getYear":"","getYearFlag":"","insuredYear":' + expire + ',"insuredYearFlag":"A","mult":1,"payEndYear":' + \
                       dt[
                           "interval"] + ',"payEndYearFlag":"Y","payIntv":"12","prem":"5457","renewalFlag":"NC","riskCode":"5317","getLimit":"","cvalidate":"2020-5-12"},' + '{"amnt":"2000000","dutyCode":"5031D1","familyType":"","getRate":"","getYear":"","getYearFlag":"","insuredYear":1,"insuredYearFlag":"Y","mult":1,"payEndYear":1,"payEndYearFlag":"Y","payIntv":"12","prem":"232","renewalFlag":"NC","riskCode":"5031","getLimit":""}' + '],"saleChnl":"O"}'
        else:

            data = '{"appntInfo":{"age":22,"birthday":"1998-05-11","ifSmoke":"N","occupationCode":"3030101","sex":"M","socialSecurityFlag":"N"},"cvalidate":"2020-5-12","insuredInfo":{"age":' + \
                   dt[
                       "year"] + ',"birthday":"' + year + '-01-01","ifSmoke":"N","occupationCode":"3030101","sex":"' + \
                   dt[
                       "gender"] + '","socialSecurityFlag":"N"},"insuredRelationToAppnt":' + appnt + ',"policyInfoList":[{"amnt":"' + \
                   dt[
                       "money"] + '","dutyCode":"' + dutyCode + '","familyType":"","getRate":"","getYear":"","getYearFlag":"","insuredYear":' + expire + ',"insuredYearFlag":"A","mult":1,"payEndYear":' + \
                   dt[
                       "interval"] + ',"payEndYearFlag":"Y","payIntv":"12","prem":"5457","renewalFlag":"NC","riskCode":"5317","getLimit":"","cvalidate":"2020-5-12"}],"saleChnl":"O"}'

        # 修饰后缀
        apps = '#app-timestamp=' + str(
            timestamp) + '&app-nonce=' + app_nonce + '&app-device-no=H5-' + app_device + ''
        params = data + apps
        headers = domain[self.name]["header"]
        headers["App-Device-No"] = "H5-" + app_device
        headers["App-Nonce"] = app_nonce
        headers["App-Timestamp"] = str(timestamp)
        headers["App-Sign"] = self.genSignature(timestamp, params)

        r = requests.post(url=domain[self.name]["url"], headers=headers, data=data)
        pprint(r.json())
        if r.status_code == 200 and r.json()["success"] != "false":
            if dt["medicalDuty"] == "1":
                prices = [int(price["prem"]) for price in r.json()["data"]["paCalResultList"]]
                price = Helper.decimalParse(sum(prices))
                data = {
                    "name": self.name,
                    "id": dt["id"],
                    "price": price
                }
                print(data)
                mysql.updatePrice(data)
            else:
                price = Helper.decimalParse(r.json()["data"]["paCalResultList"][0]["prem"])
                data = {
                    "name": self.name,
                    "id": dt["id"],
                    "price": price
                }
                print(data)
                mysql.updatePrice(data)
        else:
            data = {
                "name": self.name,
                "id": dt["id"],
                "state": 3
            }
            print("\n/*产品价格更新失败:%d*/" % dt["id"])
            mysql.updateTask(data)

    # 生成hmacsha256加密
    def genSignature(self, timestamp=None, params=None):
        # 秘钥
        secret_key = "aeonlife@WSX#$%&"

        signature = hmac.new(secret_key.encode("utf-8"), params.encode("utf-8"), digestmod=hashlib.sha256).hexdigest()

        return signature

    # 生成headers参数
    def genAppParam(self):
        js = '''
        function i() {
            return Math.random().toString(36).substr(2)
        }
        '''
        cxt = execjs.compile(js)
        appParam = cxt.call("i")
        return appParam

    def startProcess(self):
        threads = []
        for i in range(3):
            mysql = MysqlClient()
            t = Thread(target=Helper.runProcess, args=(mysql, self.name, self.requestJson))
            t.start()
            threads.append(t)
        for t in threads:
            t.join()
